﻿using SGA.Encript;
using SGA.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace SGA.Authentication.Admin
{
    public partial class Register : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            System.Threading.Thread.Sleep(3000);
        }       

        /// <summary>
        ///  Method to verify if the deleting data is valid
        ///  and to delete membership (System.Web.Security) and user at role
        ///  this is to ensure funcional requirements nr 4
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void LVSystemUsers_ItemDeleting(object sender, ListViewDeleteEventArgs e)
        {
            try
            {
                int id = (int)(e.Keys[0]);
                SystemUsers deletingUser;
                using (var bd = new MailingEntities())
                {
                    var query = (from member in bd.SystemUsers
                                 where member.Id == id
                                 select member).SingleOrDefault();
                    deletingUser = query;
                }

                if (deletingUser != null)
                {
                    Membership.DeleteUser(deletingUser.Username, true);
                    DeleteUserRoles(deletingUser.Username);

                    NotificationLabel.Text = String.Format("O {0} foi removido com sucesso.", deletingUser.Name);
                    NotificationLabel.CssClass = "mySuccess";
                    clearTextBox();
                    UsernameTextBox.Enabled = true;
                    SaveButton.Visible = true;
                    UpdateButton.Visible = false;

                }

            }

            catch (Exception ex)
            {
                e.Cancel = true;
                NotificationLabel.Text = String.Format("{0}", ex.Message);
                NotificationLabel.CssClass = "myAlert";
            }
        }             

        /// <summary>
        /// Method to delete user from role
        /// </summary>
        /// <param name="username"></param>
        private void DeleteUserRoles(string username)
        {
            foreach (var role in Roles.GetRolesForUser(username))
                Roles.RemoveUserFromRole(username, role);
        }

        protected void LVSystemUsers_ItemCommand(object sender, ListViewCommandEventArgs e)
        {
            if (e.CommandName == "Edit")
            {                
                int id = Convert.ToInt32(e.CommandArgument.ToString());
                SaveButton.Visible = false;
                UpdateButton.Visible = true;
                UsernameTextBox.Enabled = false;
                bindUser(id);
            }
        }

        private void bindUser(int id)
        {
            using (var bd = new MailingEntities())
            {
                SystemUsers user = (from member in bd.SystemUsers
                                    where member.Id == id
                                    select member).SingleOrDefault();
                if (user != null)
                {
                    MembershipUser u = Membership.GetUser(user.Username);
                    NameTextBox.Text = user.Name;
                    UsernameTextBox.Text = user.Username;
                    AliasTextBox.Text = user.Alias;
                    PasswordTextBox.Attributes.Add("value", u.GetPassword());
                    DropDownListRole.SelectedValue = user.AccessRoles.Role;
                    EnableCheckBox.Checked = (bool)user.Enable;
                    IdUserTextBox.Value = user.Id.ToString();
                }
            }
        }

        /// <summary>
        /// Method to verify if the inserting data is valid
        /// and to create membership user (System.Web.Security) and add user to role
        /// this is to ensure funcional requirements nr 1,2,3,5
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void SaveButton_Click(object sender, EventArgs e)
        {
            try
            {                
                SystemUsers newUser = new SystemUsers();
                newUser.Name = NameTextBox.Text;
                newUser.Username = UsernameTextBox.Text;
                newUser.Alias = AliasTextBox.Text;
                newUser.Enable = true;
                using (var bd = new MailingEntities())
                {
                    var query = from member in bd.SystemUsers
                                where member.Alias == newUser.Alias
                                select member;
                    if (query.Count() > 0)
                    {
                        throw new Exception("Alias já existe. Escolha outro Alias.");
                    }

                    var queryRole = (from role in bd.AccessRoles
                                     where role.Role == DropDownListRole.SelectedValue
                                     select role).SingleOrDefault();

                    newUser.AccessRolesId = queryRole.Id;
                    Membership.CreateUser(newUser.Username, PasswordTextBox.Text, "phorbs@gmail.com");
                    Roles.AddUserToRole(newUser.Username, DropDownListRole.SelectedValue);
                    bd.SystemUsers.Add(newUser);
                    bd.SaveChanges();
                }

                LVSystemUsers.DataBind();
                NotificationLabel.Text = String.Format("O {0} foi criado com sucesso", newUser.Name);
                NotificationLabel.CssClass = "mySuccess";

            }
            catch (MembershipCreateUserException ex)
            {
                NotificationLabel.Text = String.Format("{0}", GetErrorMessage(ex.StatusCode));
                NotificationLabel.CssClass = "myAlert";
            }
            catch (Exception ex)
            {
                NotificationLabel.Text = String.Format("{0}", ex.Message);
                NotificationLabel.CssClass = "myAlert";
            }
        }

        /// <summary>
        /// Method to get membership error
        /// </summary>
        /// <param name="status"></param>
        /// <returns></returns>
        private string GetErrorMessage(MembershipCreateStatus status)
        {
            switch (status)
            {
                case MembershipCreateStatus.DuplicateUserName:
                    return "Username already exists. Please enter a different user name.";

                case MembershipCreateStatus.DuplicateEmail:
                    return "A username for that e-mail address already exists. Please enter a different e-mail address.";

                case MembershipCreateStatus.InvalidPassword:
                    return "The password provided is invalid. Please enter a valid password value.";

                case MembershipCreateStatus.InvalidEmail:
                    return "The e-mail address provided is invalid. Please check the value and try again.";

                case MembershipCreateStatus.InvalidAnswer:
                    return "The password retrieval answer provided is invalid. Please check the value and try again.";

                case MembershipCreateStatus.InvalidQuestion:
                    return "The password retrieval question provided is invalid. Please check the value and try again.";

                case MembershipCreateStatus.InvalidUserName:
                    return "The user name provided is invalid. Please check the value and try again.";

                case MembershipCreateStatus.ProviderError:
                    return "The authentication provider returned an error. Please verify your entry and try again. If the problem persists, please contact your system administrator.";

                case MembershipCreateStatus.UserRejected:
                    return "The user creation request has been canceled. Please verify your entry and try again. If the problem persists, please contact your system administrator.";

                default:
                    return "An unknown error occurred. Please verify your entry and try again. If the problem persists, please contact your system administrator.";
            }
        }

        protected void ClearButton_Click(object sender, EventArgs e)
        {
            clearTextBox();
            UsernameTextBox.Enabled = true;
            SaveButton.Visible = true;
            UpdateButton.Visible = false;
        }

        private void clearTextBox()
        {
            NameTextBox.Text = string.Empty;
            UsernameTextBox.Text = string.Empty;
            AliasTextBox.Text = string.Empty;
            PasswordTextBox.Attributes.Remove("value");
        }

        /// <summary>
        /// Method to verify if the updating data is valid
        /// and to update membership (System.Web.Security) and user role
        /// this is to ensure funcional requirements nr 1,5
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void UpdateButton_Click(object sender, EventArgs e)
        {
            try
            {
                int id = Convert.ToInt32(IdUserTextBox.Value);
                using (var bd = new MailingEntities())
                {
                    SystemUsers user = (from member in bd.SystemUsers
                                        where member.Id == id
                                        select member).SingleOrDefault();
                    if (user.Alias != AliasTextBox.Text)
                    {
                        var query = from member in bd.SystemUsers
                                    where member.Alias == AliasTextBox.Text
                                    select member;
                        if (query.Count() > 0)
                        {
                            throw new Exception("Alias já existe. Escolha outro Alias.");
                        }
                    }
                    AccessRoles queryRole = (from role in bd.AccessRoles
                                             where role.Role == DropDownListRole.SelectedValue
                                             select role).SingleOrDefault();

                    user.Name = NameTextBox.Text;
                    user.Alias = AliasTextBox.Text;
                    user.Enable = EnableCheckBox.Checked;
                    user.AccessRolesId = queryRole.Id;

                    MembershipUser memberShip = Membership.GetUser(user.Username);
                    if (memberShip.GetPassword() != PasswordTextBox.Text)
                    {
                        memberShip.ChangePassword(memberShip.ResetPassword(), PasswordTextBox.Text);
                    }

                    memberShip.IsApproved = EnableCheckBox.Checked;

                    if (!Roles.IsUserInRole(memberShip.UserName, DropDownListRole.SelectedValue))
                    {
                        DeleteUserRoles(memberShip.UserName);
                        Roles.AddUserToRole(memberShip.UserName, DropDownListRole.SelectedValue);
                    }

                    bd.SaveChanges();
                    Membership.UpdateUser(memberShip);
                    LVSystemUsers.DataBind();
                    NotificationLabel.Text = String.Format("O {0} foi atualizado com sucesso.", memberShip.UserName);
                    NotificationLabel.CssClass = "mySuccess";
                }
            }
            catch (Exception ex)
            {
                NotificationLabel.Text = String.Format("{0}", ex.Message);
                NotificationLabel.CssClass = "myAlert";
            }
        }
    }
}